#!/usr/bin/php
<?php 
/*
 * Copyright (C) 2013-2014 RuneAudio Team
 * http://www.runeaudio.com
 *
 * RuneUI
 * copyright (C) 2013-2014 - Andrea Coiutti (aka ACX) & Simone De Gregori (aka Orion)
 *
 * RuneOS
 * copyright (C) 2013-2014 - Simone De Gregori (aka Orion) & Carmelo San Giovanni (aka Um3ggh1U)
 *
 * RuneAudio website and logo
 * copyright (C) 2013-2014 - ACX webdesign (Andrea Coiutti)
 *
 * This Program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3, or (at your option)
 * any later version.
 *
 * This Program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with RuneAudio; see the file COPYING.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.txt>.
 *
 *  file: command/refresh_nics
 *  version: 1.3
 *  coder: Simone De Gregori
 *
 */
// common include
ini_set('display_errors', '1');
// ini_set('error_reporting', -1);
ini_set('error_log', '/var/log/runeaudio/refresh_nics.log');
// Connect to Redis backend
$redis = new Redis();
$redis->connect('/tmp/redis.sock');
include('/var/www/app/libs/runeaudio.php');
include '/var/www/app/libs/vendor/ziegler/iwlist-parser.class.php';
// startup - lock the scan system
runelog('--------------------------- lock the scan system ---------------------------');
$redis->Set('lock_wifiscan', 1);
// random delay
$sleep = rand(1000000, 2000000);
usleep($sleep);
runelog('random delay: ', $sleep);
// startup - collect system data
runelog('--------------------------- collect system data ---------------------------');
$excluded_nics = array('ifb0', 'ifb1');
$active_nics = sysCmd("ifconfig | grep UP | cut -d ':' -f 1");
$detected_nics = sysCmd("ip addr |grep \"BROADCAST,\" |cut -d':' -f1-2 |cut -d' ' -f2");
$detected_nics = array_diff($detected_nics, $excluded_nics);
$inactive_nics = array_diff($detected_nics, $active_nics);
$configured_nics = array_map("trim", sysCmd("netctl list | cut -d ' ' -f 2,3"));
$removed_nics = array_diff($configured_nics, $detected_nics);
// debug
runelog('########### active_nics ########### ', $active_nics);
// print_r($active_nics);
// print_r($excluded_nics);
runelog('########### excluded_nics ########### ', $excluded_nics);
// print_r($detected_nics);
runelog('########### detected_nics ########### ', $detected_nics);
// print_r(array_diff($detected_nics,$active_nics));
// print_r($configured_nics);
runelog('########### configured_nics ########### ', $configured_nics);
// print_r(array_diff($configured_nics,$detected_nics));
// print_r($removed_nics);
runelog('########### removed_nics ########### ', $removed_nics);
// handle inactive nics
runelog('--------------------------- handle inactive nics ---------------------------');
if (!empty($inactive_nics)) {
    foreach($inactive_nics as $nic) {
        $wireless = sysCmd("iwconfig ".$nic." | grep 'no wireless'");
        if (empty($wireless)) {
            // activate link
            runelog('########### activate currently inactive wifi nic: '.$nic);
            sysCmd('ip link set '.$nic.' up');
            // start wpa_supplicant
            runelog('########### start wpa_supplicant for wifi nic: '.$nic);
            sysCmd('systemctl start wpa_supplicant@'.$nic);
            // check if the nic is unconfigured (= without an existing netctl profile)
            if (empty(sysCmd('ls /etc/netctl/ | grep '.$nic))) {
                // create a new standard (dhcp) wifi netctl profile
                $args = new stdClass;
                $args->name = $nic;
                $args->wireless = '1';
                $args->dhcp = '1';
                wrk_netconfig($redis, 'writecfg', $args, 1);
            }
            // check wpa_supplicant status
            // if (empty(sysCmd('ls /etc/systemd/system/multi-user.target.wants/ | grep wpa_supplicant@'.$nic))) {
                // enable wpa_supplicant
                // runelog('########### enable wpa_supplicant for wifi nic: '.$nic);
                // sysCmd('systemctl enable wpa_supplicant@'.$nic);
            // }
            // enable netctl profile
            // if (empty(sysCmd('ls /etc/systemd/system/multi-user.target.wants/ | grep netctl@'.$nic))) {
                // runelog('########### enable netctl for wifi nic: '.$nic);
                // sysCmd('netctl enable '.$nic);
            // }
        }
    }
}
unset($nic);
runelog('--------------------------- handle active nics ---------------------------');
// check if there is a stored profile
// refesh visible wifi networks.
$iw = new iwlist_parser;
// debug
// print_r($iw->parseScanDev( 'wlan0' ));
wrk_netconfig($redis, 'setnics');
$nics = wrk_netconfig($redis, 'getnics');
// debug
// print_r($nics);
foreach ($nics as $nic => $nicdetail) {
    if ($nicdetail->wireless === 1) {
        // check and activate wpa_supplicant
        if (empty(sysCmd("ps x | grep '\-c\/etc\/wpa_supplicant\/wpa_supplicant.conf'"))) {
            runelog('########### start wpa_supplicant for nic: '.$nic);
            sysCmd('systemctl start wpa_supplicant@'.$nic);
            }
        // check and activate netctl@nic profile
        if (empty(sysCmd('netctl list | grep '.$nic.' | grep \*'))) {
            runelog('########### start netctl profile for nic: '.$nic);
                if(!empty(sysCmd('netctl start '.$nic))) {
                    runelog('########### ZERO condition reached for nic: '.$nic.' restart link and wpa_supplicant helper');
                    sysCmd('ip link set '.$nic.' up');
                    sysCmd('systemctl start wpa_supplicant@'.$nic);
                }
            }
        // temp
        $scan = $iw->parseScanDev( $nic );
        $redis->set('wlans',json_encode($scan));
        // debug
        // print_r($scan);
        foreach ($scan as $nicname => $nicscan) {
            foreach ($nicscan as $count => $wlan) {
                foreach ($wlan as $key => $value) {
                    $wlans[$count]['nic'] = $nicname;
                    if ($key === 'ESSID') {
                        $wlans[$count][$key] = $value;
                        if ($nicdetail->currentssid === $value) {
                            $wlans[$count]['connected'] = 1;
                        } else {
                            $wlans[$count]['connected'] = 0;
                        }
                    }
                    if ($key === 'Encryption key') $wlans[$count]['encryption'] = $value;
                }
            }
        } 
        // debug
        // print_r($wlans);
        // render wlans channel
        // $wlans = json_encode($wlans);
        $wlans_profiles = $redis->hGetAll('wlan_profiles');
        $i = count($wlans);
        foreach ($wlans_profiles as $profile => $details) {
            $i++;
            $details = json_decode($details);
            $stored_profiles[$i]['nic'] = $details->nic;
            if ($details->encryption !== 'open') {
                $stored_profiles[$i]['encryption'] = 'on';
            } else {
                $stored_profiles[$i]['encryption'] = 'off';
            }
            $stored_profiles[$i]['ESSID'] = $details->ssid;
            if ($nicdetail->currentssid === $details->ssid) {
                $stored_profiles[$i]['connected'] = 1;
            } else {
                $stored_profiles[$i]['connected'] = 0;
            }
            $stored_profiles[$i]['storedprofile'] = 1;
            $wlans[] = $stored_profiles[$i];
        }
        $wlans = json_encode($wlans);
        // $wlans = json_encode(array_merge($wlans, $stored_profiles));
        ui_render('wlans', $wlans);
        runelog('wlans response: ', $wlans);
    }
}
// send nics status to RuneUI
ui_render('nics', json_encode($nics));
unset($nic);
// handle removed nics
runelog('--------------------------- handle removed nics ---------------------------');
if (!empty($removed_nics)) {
    foreach($removed_nics as $nic) {
        // check for orphan netctl startup profiles
        if (!empty(sysCmd('ls /etc/systemd/system/multi-user.target.wants/ | grep '.$nic))) {
            // disable orphan netctl profiles
            // sysCmd("rm -f /etc/systemd/system/multi-user.target.wants/netctl@".$nic.".service')");
            // sysCmd("systemctl disable netctl@".$nic.".service')");
            runelog('########### disable netctl profiles for nic: '.$nic);
            sysCmd('netctl disable '.$nic);
        }
        // check wpa_supplicant startup status
        // if (!empty(sysCmd('ls /etc/systemd/system/multi-user.target.wants/ | grep wpa_supplicant@'.$nic))) {
            // disable wpa_supplicant autostart 
            // runelog('########### disable wpa_supplicant autostart for nic: '.$nic);
            // sysCmd("rm -f /etc/systemd/system/multi-user.target.wants/wpa_supplicant@".$nic.".service')");
            // sysCmd('systemctl disable wpa_supplicant@'.$nic.'.service');
        // }
    }
}
// end - unlock the scan system
runelog('--------------------------- unlock the scan system ---------------------------');
$redis->Set('lock_wifiscan', 0);
// colse Redis connection
$redis->close();
